package org.noahsark.core.domainmodel;

import java.io.Serializable;

import javax.persistence.Transient;

import org.apache.commons.lang.builder.CompareToBuilder;
import org.noahsark.core.domainmodel.IEntity;

@SuppressWarnings("rawtypes")
public abstract class BaseEntity<K extends Serializable> implements
		Serializable, Comparable<BaseEntity>, IEntity<K>, Cloneable {

	private static final long serialVersionUID = 1L;

	public abstract K getId();

	public abstract void setId(K id);

	/**
	 * return hash code
	 */
	public int hashCode() {
		if (getId() == null) {
			return super.hashCode();
		}
		return getId().hashCode();
	}

	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}

		if (obj == null) {
			return false;
		}

		if (!(obj instanceof BaseEntity)) {
			return false;
		}

		final BaseEntity other = (BaseEntity) obj;
		if (getId() == null) {
			if (other.getId() != null) {
				return false;
			} else {
				if (this.hashCode() == other.hashCode()) {
					return true;
				} else {
					return false;
				}
			}
		} else {
			if (!getId().equals(other.getId())) {
				return false;
			}
		}

		return true;
	}
	
	public int compareTo(BaseEntity otherEntity) {
        if (otherEntity == null) {
            return 1;
        }
        if (this.getId() == null) {
            return -1;
        }
        if (this.getId().getClass() != otherEntity.getId().getClass()) {
            return 1;
        }
        return new CompareToBuilder().append(this.getId(), otherEntity.getId()).toComparison();
    }
	
	public BaseEntity clone() {
        try {
            return (BaseEntity) super.clone();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
	
	@Transient
	public boolean isNew() {
        return getId() == null;
    }
}
